デザインパターン:テキストファイル内の類似しているが異なるスキーマの解析
-
22-07-2019 - |
質問
ご協力ありがとうございます。この問題に適用できる(設計)パターンがあるかどうか疑問に思っています。
類似しているが異なる形式のテキストファイルから値を解析、処理、および抽出しようとしています。
具体的には、さまざまなWebサイトからオンラインポーカーハンド履歴ファイルを受け入れ、特定のデータフィールド(ハンド#、DateTime、プレーヤー)を解析する処理エンジンを構築しています。ファイルを解析するためのロジックは、フォーマットごとにわずかに異なる必要がありますが、抽出された値の処理は同じになります。
最初に考えたのは、「スキーマ」を受け入れるクラスを1つだけ作成することでした。各ファイルの種類および解析/プロセスごとに。これに対するより良い解決策があると確信しています。
ありがとう!
ボーナスポイント: C#の特定の実装ヒント。
他のヒント
"プロバイダー"パターンはあなたが探しているものです...それはADO.Netで使用されているものです。各データベースベンダーには、個別のデータ「プロバイダー」があります。 「知っている」こと特定のDBベンダー製品からデータを読み取る方法。ただし、標準形式(インターフェイス)でダウンストリームシステムに配信します。小さな「プロバイダ」を記述します。 「知っている」コンポーネント(単一のクラスで十分)さまざまなWebサイトポーカー履歴データプロバイダーのそれぞれの形式で、データを読み取るアップストリームシステムにまったく同じ方法でそのデータを公開します...
戦略パターンが必要なように聞こえます。これにより、さまざまな方法でアルゴリズムを実装できます。
まず、「オンラインポーカーハンド履歴」を作成します。 モデル。このモデルはデータを表し、ソースから独立してこのデータを処理できます。次に、ファイルの情報をモデルに変換できる必要があるさまざまなソース形式ごとにプロバイダを作成します。
編集:例:
public interface IDataProvider
{
IOnlinePokerInfo ParseFileInformation(FileInfo input);
}
public interface IOnlinePokerInfo
{
int Hand { get; set; }
DateTime DateInfo { get; set; }
List<IPlayer> Players { get; set; }
void ProcessInformation();
}
public interface IPlayer
{
string Name { get; set; }
}
public class MyOnlinePokerInfo : IOnlinePokerInfo
{
private int hand;
private DateTime date;
private List<IPlayer> players;
public int Hand { get { return hand; } set { hand = value; } }
public DateTime DateInfo { get { return date; } set { date = value; } }
public List<IPlayer> Players { get { return players; } set { players = value; } }
public MyOnlinePokerInfo(int hand, DateTime date)
{
this.hand = hand;
this.date = date;
players = new List<IPlayer>();
}
public MyOnlinePokerInfo(int hand, DateTime date, List<IPlayer> players)
: this(hand, date)
{
this.players = players;
}
public void AddPlayer(IPlayer player)
{
players.Add(player);
}
public void ProcessInformation()
{
Console.WriteLine(ToString());
}
public override string ToString()
{
StringBuilder info = new StringBuilder("Hand #: " + hand + " Date: " + date.ToLongDateString());
info.Append("\nPlayers:");
foreach (var s in players)
{
info.Append("\n");
info.Append(s.Name);
}
return info.ToString();
}
}
public class MySampleProvider1 : IDataProvider
{
public IOnlinePokerInfo ParseFileInformation(FileInfo input)
{
MyOnlinePokerInfo info = new MyOnlinePokerInfo(1, DateTime.Now);
IPlayer p = new MyPlayer("me");
info.AddPlayer(p);
return info;
}
}
public class MySampleProvider2 : IDataProvider
{
public IOnlinePokerInfo ParseFileInformation(FileInfo input)
{
MyOnlinePokerInfo info = new MyOnlinePokerInfo(2, DateTime.Now);
IPlayer p = new MyPlayer("you");
info.AddPlayer(p);
return info;
}
}
public class MyPlayer : IPlayer
{
private string name;
public string Name { get { return name; } set { name = value; } }
public MyPlayer(string name)
{
this.name = name;
}
}
public class OnlinePokerInfoManager
{
static void Main(string[] args)
{
List<IOnlinePokerInfo> infos = new List<IOnlinePokerInfo>();
MySampleProvider1 prov1 = new MySampleProvider1();
infos.Add(prov1.ParseFileInformation(new FileInfo(@"c:\file1.txt")));
MySampleProvider2 prov2 = new MySampleProvider2();
infos.Add(prov2.ParseFileInformation(new FileInfo(@"c:\file2.log")));
foreach (var m in infos)
{
m.ProcessInformation();
}
}
}
また、到達時間のアクションがあるコマンドパターンの使用を検討することもできます。処理する必要があるファイルの種類。これにより、すべての形式に柔軟性を持たせ、プロセスに必要な一貫したパラメーターを順守することができます。
別の利点は、他の形式のコードをリファクタリングすることなく、新しいファイル形式ごとに新しいアクションを作成できることです。